#include "context.h"
#include "joystick_device.h"
#include "udp_backend.h"

Context::Context(QObject *parent) : QObject{parent}
{
    js = new JoystickDevice(this);
    if (!js->InitDevice("dev/ttyS4", 115200))
        qDebug("Init joystick failed");
    js->SetRemapParam(
        QVector<float>{0.7827035, 0.6280165, 0.785927, 0.628823, 0.7822985, 0.6276115, 0.78310353, 0.6171365});
    key = new KeyDevice(this);
    if (!key->InitDevice("dev/ttyS5", 115200))
        qDebug("Init joystick failed");
    udp = new UDPBackend(this);
    address = QHostAddress("192.168.1.100");
    port = 8888;
    // frameControl = new Frame();
    frameDrive = new FrameDrive(this);
    frameControl = new FrameControl(this);
    frameState = new FrameState(this);

    // user=>frame=>udp=>chassis
    connect(frameControl, &::Frame::OnFrameChangedByLocal, this,
            [&]() { udp->SendFrame(Frame::WrapFrame(*frameControl), address, port); });
    connect(frameDrive, &::Frame::OnFrameChangedByLocal, this,
            [&]() { udp->SendFrame(Frame::WrapFrame(*frameDrive), address, port); });

    // chassis=>udp=>ui
    connect(udp, &UDPBackend::OnReceiveFrame, this, [&](const QByteArray &frameData) {
        unsigned int id = Frame::PeekFrameID(frameData);
        Frame *frame = nullptr;
        switch (id)
        {
        case 0x00000030:
            frame = frameDrive;
            throw std::runtime_error("this frame should not be received by rc");
            break;
        case 0x00000031:
            frame = frameControl;
            throw std::runtime_error("this frame should not be received by rc");
            break;
        case 0x00000032:
            frame = frameState;
            break;
        default:
            throw std::runtime_error("unknown frame id:" + std::to_string(id));
        }
        frame->DecodeFromBytes(frameData.mid(8, frame->Size()));
        emit OnFrameChangedByRemote(frame->GetFrameName());
    });
}
